/*
 * File:   driver_buzzer.c
 * Author: Ich
 *
 * Created on 12. Januar 2014, 16:59
 *
 */

#include <plib.h>
#include "driver_buzzer.h"
#include "config_buzzer.h"
#include "driver_timer.h"
#include "config_dma.h"
/*******************************************************************************
 *  private preprocessing definitions
 */

 /*******************************************************************************
 *  private variables
 */
static const UINT16 DMA_CHN = CFG_DMA_0;
static BOOL isBuzzerOn = FALSE;

/*******************************************************************************
 *  private functions
 */

 /*******************************************************************************
 *  public variables (defined by external)
 */


/*******************************************************************************
 *  public functions
 */

void drvBuzzer_init (void)
{
    // Configure the Output Compare channels for PWM mode using Timer3
    // setup output compare channel #4 - RD3
    OpenOC4(OC_ON | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);

    drvBuzzer_off();
    drvTmr3_on(CFG_BUZZER_FREQ_MIDDLE);
}

/* buzzer on = pwm port on */
void drvBuzzer_on(void)
{
   isBuzzerOn = TRUE;
   drvTmr3_setCntTarget(CFG_BUZZER_FREQ_MIDDLE);

   /* PWM with duty cycle of 50% */
   SetDCOC4PWM(drvTmr3_getCntTarget()/2);
}

/* buzzer off = pwm port off */
void drvBuzzer_off(void)
{
    isBuzzerOn = FALSE;
    SetDCOC4PWM(0);
}

/* return: true = ON */
BOOL drvBuzzer_isOn(void)
{
    return isBuzzerOn;
}

void drvBuzzer_setSignalWithDMA(const UINT16 *pSignalData, UINT16 dataLen)
{
    drvBuzzer_init();
    // Open the desired DMA channel.
    // We enable the AUTO option, we'll keep repeating the same transfer over and over.
    DmaChnOpen(DMA_CHN, 0, DMA_OPEN_ENABLE);

    // Set the transfer parameters: source & destination address, source & destination size, number of bytes per event
    unsigned short * pDmaSrc = (void*) pSignalData;
    unsigned short * pDmaDst = (void*) &OC4RS;
    DmaChnSetTxfer( DMA_CHN,
                    pDmaSrc,
                    pDmaDst,
                    sizeof(*pSignalData)*dataLen,
                    sizeof(*pSignalData),
                    sizeof(*pSignalData));

    // Set the transfer event control: what event is to start the DMA transfer
    DmaChnSetEventControl(DMA_CHN, DMA_EV_START_IRQ(_TIMER_4_IRQ));

    // Once we configured the DMA channel we can enable it
    // Now it's ready and waiting for an event to occur...
    DmaChnEnable(DMA_CHN);

    drvTmr4_reset();
}